package com.zhiyu.common;

import java.util.ArrayList;
import java.util.List;

import com.auth0.jwt.exceptions.TokenExpiredException;
import com.zhiyu.entity.DO.AccountDO;
import com.zhiyu.entity.DO.PermissionDO;
import com.zhiyu.entity.DO.RoleDO;
import com.zhiyu.entity.DO.UserDO;
import com.zhiyu.exception.TokenException;
import com.zhiyu.mapper.UserMapper;
import com.zhiyu.service.AccountService;
import com.zhiyu.service.UserService;
import com.zhiyu.util.JWTUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyRealm extends AuthorizingRealm {
	private static final Logger LOGGER = LogManager.getLogger(MyRealm.class);

	@Autowired
	private JWTUtil jwtUtil;

	@Autowired
	private UserService userService;

	@Autowired
	private AccountService accountService;

	@Override
	public boolean supports(AuthenticationToken token) {
		return token instanceof JWTToken;
	}

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		int userId = Integer.valueOf(jwtUtil.getSubject(principals.toString()));

		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

		simpleAuthorizationInfo.addRoles(userService.findRoles(userId));

		List<PermissionDO> permissions = userService.findPermissions(userId);
		List<String> actions = new ArrayList<String>();
		for(PermissionDO permissionDO : permissions)
			actions.add(permissionDO.getAction());
		simpleAuthorizationInfo.addStringPermissions(actions);

		return simpleAuthorizationInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String jwtToken = (String) token.getCredentials();
		String userId = jwtUtil.getSubject(jwtToken);

		if(userId == null || userService.findById(Integer.valueOf(userId)) == null) {
			throw new AuthenticationException("token无效");
		}

		return new SimpleAuthenticationInfo(jwtToken, jwtToken, getName());
	}

	public String getName() {
		return "myRealm";
	}
}
